package com.markerhub.security;

import cn.hutool.core.util.StrUtil;
import com.markerhub.common.exception.JwtException;
import com.markerhub.entity.SysUser;
import com.markerhub.service.SysUserService;
import com.markerhub.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

	@Autowired
	JwtUtils jwtUtils;

	@Autowired
	SysUserService sysUserService;
	@Autowired
	UserDetailsServiceImpl userDetailsServiceImpl;

	public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
		super(authenticationManager);
	}

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

		String jwt = request.getHeader(jwtUtils.getHeader());
		if (StrUtil.isBlankOrUndefined(jwt)) {
			chain.doFilter(request, response);
			return;
		}

		Map<String,Object> claims = jwtUtils.parseToken(jwt);
		if (claims == null) {
			throw new JwtException("不存在该用户，jwt异常");
		}
		if (jwtUtils.isTokenExpired(jwt)) {
			throw new JwtException("token已过期");
		}

		String username = (String) claims.get("username");
		log.info("用户-{}，正在登陆！", username);
		// 获取用户的权限等信息
		SysUser sysUser = sysUserService.getByUsername(username);
		UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
				= new UsernamePasswordAuthenticationToken(username, null, userDetailsServiceImpl.getUserAuthority(sysUser.getId()));
		SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
		chain.doFilter(request, response);
	}
}
